package com.zb.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.zb.constant.NetworkConstant;
import com.zb.constant.WorkConstant;
import com.zb.entity.*;
import com.zb.excel.converter.WorkConverter;
import com.zb.extend.WorkFeeDetailExtend;
import com.zb.extend.WorkNetworkExtend;
import com.zb.order.service.ConWorkFeeService;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.service.impl.WorkServiceLog;
import com.zb.utils.ZbOrderNoUtil;
import com.zb.view.ViewNetworkEmpDetail;
import com.zb.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author WEN
 * @Date 2023/10/25 0025
 **/
@Service
public class ConWorkFeeServiceImpl implements ConWorkFeeService {
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjNetworkService networkService;
    @Resource
    private ViewNetworkEmpDetailService viewNetworkEmpDetailService;
    @Resource
    private ZjWorkFeeService workFeeService;
    @Resource
    private ZjWorkFeeDetailService workFeeDetailService;
    @Resource
    private ZjFactoryAccountBalanceService factoryAccountBalanceService;
    @Resource
    private ZjWorkDetailService workDetailService;

    // 保存或修改工单服务费用
    @Override
    @Transactional
    public void save(AccounLoginInfo loginInfo, WorkFeeVo workFeeVo) {
        workOrderService.checkOrderStatus(workFeeVo.getWorkId());
        ZjWorkOrder workOrder = workOrderService.getById(workFeeVo.getWorkId());
        Assert.notNull(workOrder, "服务工单数据不存在");
        Assert.isTrue(workOrder.getStatus() == WorkConstant.WORK_STATUS_3, "工单单号["+ workOrder.getCode() +"]的流程状态处于非[处理中]状态，不可跨流程申请服务费用或有其他操作");

        ZjWorkFee fee = new ZjWorkFee();
        fee.setId(workFeeVo.getId());
        fee.setApplyRemark(workFeeVo.getRemark());

        WorkLogVo logVo = null;
        if (null != fee.getId()) {
            ZjWorkFee workFee = workFeeService.getById(fee.getId());
            Assert.isTrue(workFee.getStatus() != WorkConstant.WORK_FEE_STATUS_1, "工单服务费用单号["+ workFee.getCode() +"]的服务费已审核，不可重复操作");

            workFeeService.updateById(fee);
            logVo = new WorkLogVo(loginInfo, workFeeVo.getWorkId(), "修改申请工单服务费用项目，等待审核",
                    "工单客服【" + loginInfo.getName() + "】修改申请工单服务项目成功，等待审核");
        } else {
            ViewNetworkEmpDetail networkEmpDetailView = viewNetworkEmpDetailService.getManagerByNetworkId(workOrder.getNetworkId());
            ZjNetwork network = networkService.getById(workOrder.getNetworkId());

            fee.setId(IdWorker.getId());
            fee.setCustAccId(loginInfo.getCustAccId());
            fee.setWorkId(workFeeVo.getWorkId());
            fee.setWorkNo(workOrder.getCode());
            fee.setCode(ZbOrderNoUtil.orderFeeNo(loginInfo.getCustAccId()));
            fee.setStatus(WorkConstant.WORK_FEE_STATUS_1);
            fee.setNetworkId(workOrder.getNetworkId());
            fee.setNetworkManagerEmpId(networkEmpDetailView.getId());
            fee.setNetworkEngineerEmpId(workOrder.getNetworkEmpId());
            fee.setApplyEmpType(WorkConstant.APPLY_OR_CHECK_EMP_TYPE_1);
            fee.setApplyEmpId(loginInfo.getId());
            fee.setApplyEmp(loginInfo.getName());
            fee.setReceive(network.getCategory() != NetworkConstant.CATEGORY_2);
            fee.setReviewEmpId(0L);
            fee.setReviewEmp("");
            fee.setReviewRemark("");
            workFeeService.save(fee);

            ZjWorkDetail detail = new ZjWorkDetail();
            detail.setId(workOrder.getId());
            detail.setNoReviewApplyWorkFeeNum(1);
            workDetailService.updateOrderEventById(detail);
            logVo = new WorkLogVo(loginInfo, workFeeVo.getWorkId(), "申请工单服务费用项目，等待审核", "申请服务项目成功，等待审核");
        }
        workFeeDetailService.save(loginInfo.getCustAccId(), fee.getId(), workOrder.getId(), workFeeVo.getFeeDetails(), workFeeVo.getDelFeeDetailIds());
        workOrderService.updateNewAdvanceOrWaitCopeEventById(workOrder.getId(), workOrder.getNewAdvance(), workOrder.getWaitCopeEvent() +1);
        WorkServiceLog.saveService(logVo);
        WorkServiceLog.saveServiceFeeLog(new WorkFeeLogVo(loginInfo, fee.getWorkId(), fee.getId(), logVo.getEvent(), logVo.getContent()));
    }

    // 获取工单服务费用项目列表
    @Override
    public Map<String, Object> getList(Long custAccId, OrderFeeListSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        List<ZjWorkFee> workFeeList = workFeeService.getList(custAccId, selectVo);
        List<WorkFeeDetailExtend> feeDetailExtends = workFeeDetailService.getByWorkFeedIds(workFeeList.stream().map(ZjWorkFee::getId).toList());
        List<Long> workIds = workFeeList.stream().map(ZjWorkFee::getWorkId).distinct().toList();
        List<WorkNetworkExtend> networkExtendList = workOrderService.getNetworkByWorkIds(workIds);

        List<OrderFeeListVo> voList = workFeeList.stream().map(fee -> {
            OrderFeeListVo vo = new OrderFeeListVo();
            BeanUtil.copyProperties(fee, vo);
            vo.setFeeNo(fee.getCode());
            vo.setApplyEmp("【" + (fee.getApplyEmpType() == 1? "客服" :
                    fee.getApplyEmpType() == 2? "服务商移动端" :
                    fee.getApplyEmpType() == 3? "乐开伙伴云" :
                    fee.getApplyEmpType() == 4? "品牌商家" :
                            "客服"
            ) + "】" + fee.getApplyEmp());
            vo.setCreateTime(fee.getGmtCreate());
            vo.setUpdateTime(fee.getGmtUpdate());
            List<WorkFeeDetailExtend> extendList = feeDetailExtends.stream().filter(f -> Objects.equals(f.getWorkFeeId(), fee.getId())).toList();
            vo.setSettlementType(extendList.stream().map(e -> {
                return WorkConverter.orderFeeOrOrderSpareSettlementTypeConverter(e.getType());
            }).distinct().collect(Collectors.joining("、")));
            vo.setFeeProject(extendList.stream().map(WorkFeeDetailExtend::getName).distinct().collect(Collectors.joining("、")));
            vo.setTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setPayNetworkTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getPayNetworkPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setReceiveFactoryTotalPrice(extendList.stream().filter(f -> f.getStatus() == 2).map(feeDetail -> {
                return feeDetail.getReceiveFactoryPrice().multiply(new BigDecimal(feeDetail.getQty()));
            }).reduce(new BigDecimal("0.00"), BigDecimal::add));
            vo.setSurePrice(extendList.stream().allMatch(f -> f.getSurePriceStatus() == 2));
            vo.setNetwork(networkExtendList.stream().filter(f -> Objects.equals(f.getId(), fee.getWorkId())).map(WorkNetworkExtend::getNetwork).findFirst().orElse(""));
            return vo;
        }).toList();
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), workFeeService.getListCount(custAccId, selectVo), voList);
    }

    // 审核工单服务费用项目
    @Override
    @Transactional
    public void checkOrderFee(AccounLoginInfo loginInfo, OrderFeeCheckVo orderFeeCheckVo) {
        ZjWorkFee workFee = workFeeService.getById(orderFeeCheckVo.getId());
        Assert.isTrue(null != workFee, "工单服务费用项目ID参数["+ orderFeeCheckVo.getId() +"]的费用项目数据不存在");
        Assert.isTrue(workFee.getStatus() == WorkConstant.WORK_FEE_STATUS_1, "费用单号["+ workFee.getCode() +"]的的服务项目已审核，不可重复该审核流程");

        QueryWrapper<ZjWorkFeeDetail> feeDetailQueryWrapper = new QueryWrapper<>();
        feeDetailQueryWrapper.eq("work_fee_id", workFee.getId());
        Assert.isTrue(workFeeDetailService.count(feeDetailQueryWrapper) == orderFeeCheckVo.getFeeDetails().size(), "审核的服务费用数量与申请的服务费用数量不一至，审核时必须全部审核");
        ZjWorkOrder workOrder = workOrderService.getById(workFee.getWorkId());

        ZjWorkFee fee = new ZjWorkFee();
        fee.setId(orderFeeCheckVo.getId());
        fee.setReviewEmpId(loginInfo.getId());
        fee.setReviewEmp(loginInfo.getName());
        fee.setReviewTime(new Date());
        fee.setReviewRemark(orderFeeCheckVo.getRemark());

        List<WorkFeeDetailCheckVo> feeDetails = orderFeeCheckVo.getFeeDetails();
        WorkLogVo logVo = null;
        BigDecimal freezePrice = new BigDecimal("0.0");
        if (feeDetails.stream().anyMatch(f -> f.getStatus() == 1)) {
            fee.setStatus(WorkConstant.WORK_FEE_STATUS_1);
            logVo = new WorkLogVo(loginInfo, workFee.getWorkId(), "审核申请工单服务费用", "服务费用审核成功；\r\n备注："+ orderFeeCheckVo.getRemark());
        }else {
            if (feeDetails.stream().anyMatch(f -> f.getStatus() == 2)) {
                fee.setStatus(WorkConstant.WORK_FEE_STATUS_2);
                logVo = new WorkLogVo(loginInfo, workFee.getWorkId(), "审核申请工单服务费用", "服务费用审核成功，审核结果：已通过；\r\n备注："+ orderFeeCheckVo.getRemark());
                freezePrice = orderFeeCheckVo.getFeeDetails().stream().map(feeDetailCheckVo -> {
                    return feeDetailCheckVo.getReceiveFactoryPrice().multiply(new BigDecimal(feeDetailCheckVo.getQty()));
                }).reduce(BigDecimal::add).orElse(new BigDecimal("0.0"));
            }
            if (feeDetails.stream().allMatch(f -> f.getStatus() == 3)) {
                fee.setStatus(WorkConstant.WORK_FEE_STATUS_3);
                logVo = new WorkLogVo(loginInfo, workFee.getWorkId(), "审核申请工单服务费用", "服务费用审核成功，审核结果：已驳回；\r\n备注：" + orderFeeCheckVo.getRemark());
            }
        }
        workFeeService.updateById(fee);
        workFeeDetailService.checkOrderFee(loginInfo.getCustAccId(), orderFeeCheckVo);
        ZjWorkOrder newOrder = new ZjWorkOrder();
        newOrder.setId(workOrder.getId());
        newOrder.setNewAdvance(workOrder.getNewAdvance());
        newOrder.setWaitCopeEvent(workOrder.getWaitCopeEvent() -1);
        workOrderService.updateById(newOrder);
        ZjWorkDetail detail = new ZjWorkDetail();
        detail.setId(workOrder.getId());
        detail.setNoReviewApplyWorkFeeNum(-1);
        workDetailService.updateOrderEventById(detail);
        // 冻结品牌商家费用
        factoryAccountBalanceService.updateFreezePriceById(workOrder.getFactoryId(), freezePrice);

        WorkServiceLog.saveService(logVo);
        WorkServiceLog.saveServiceFeeLog(new WorkFeeLogVo(loginInfo, workFee.getWorkId(), fee.getId(), logVo.getEvent(), logVo.getContent()));
        // todo 对接第三方服务商
    }
}
